﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using XML_VML.Object;

namespace XML_VML
{
    public class DrawablePolyline : ContentControl, INotifyPropertyChanged
    {
        #region Points
        public static readonly DependencyProperty PointsProperty = DependencyProperty.Register(
                "Points",
                typeof(string),
                typeof(DrawableLine),
                new FrameworkPropertyMetadata("0 0 10 10 20 0"));

        private static void PointsChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs eventArgs)
        {
            var temp = dependencyObject as DrawablePolyline;
            var newvalue = (string)eventArgs.NewValue;
            if (temp != null && newvalue != null)
            {
                var rs = new List<Point>();
                var strNum = Regex.Split(newvalue, @"\d+");
                for (var i = 0; i < strNum.Length / 2; i++)
                {
                    int first, second;

                    if (!int.TryParse(strNum[i * 2].Trim(), out first) || !int.TryParse(strNum[i * 2 + 1].Trim(), out second))
                        continue;
                    var zz = new Point(first, second);
                    rs.Add(zz);
                }
                temp.GetData().Points = rs;
            }
        }

        public string Points
        {
            get
            {
                return (string)GetValue(PointsProperty);
            }
            set {
                if (Points != value)
                {
                    SetValue(PointsProperty, value);
                }
            }
        }
        #endregion

        #region StrokeColor
        public Color StrokeColor
        {
            get
            {
                if (_data.Stroke)
                {
                    try
                    {
                        var color = (Color)ColorConverter.ConvertFromString(_data.StrokeColor);
                        return color;
                    }
                    catch (Exception)
                    {
                        return Colors.Black;
                    }
                }
                return Colors.Transparent;
            }
            set { _data.StrokeColor = value.ToString(); }
        }
        #endregion

        #region StrokeWeight

        public float StrokeWeight
        {
            get { return _data.StrokeWeight; }
            set { _data.StrokeWeight = value; }
        }
        #endregion

        #region FillColor
        public Color FillColor
        {
            get
            {
                if (_data.Fill)
                {
                    try
                    {
                        var color = (Color)ColorConverter.ConvertFromString(_data.FillColor);
                        return color;
                    }
                    catch (Exception)
                    {
                        return Colors.White;
                    }
                }
                return Colors.White;
            }
            set { _data.StrokeColor = value.ToString(); }
        }
        #endregion

        private VPolyLine _data;

        public VPolyLine GetData()
        {
            return _data;
        }

        public void SetData(VPolyLine data)
        {
            _data = data;
            Points = GetStringFromPoints(_data.Points);
            OnPropertyChanged("Points");
        }

        public static string GetStringFromPoints(List<Point> list)
        {
            if (list != null && list.Count > 2)
            {
                var temp = "";
                foreach (var t in list)
                {
                    int posx = Convert.ToInt32(Math.Round(t.X, 0, MidpointRounding.ToEven));
                    int poxy = Convert.ToInt32(Math.Round(t.Y, 0, MidpointRounding.ToEven));

                    temp += posx + " " + poxy + " ";
                }
                return temp.Trim();
            }
            return "0 0 10 10 20 0";
        }

        static DrawablePolyline()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(DrawablePolyline), new FrameworkPropertyMetadata(typeof(DrawablePolyline)));
        }

        protected bool IsDragging;
        private Point _clickPosition;

        public DrawablePolyline()
        {
            MouseLeftButtonDown += ControlMouseLeftButtonDown;
            MouseLeftButtonUp += ControlMouseLeftButtonUp;
            MouseMove += ControlMouseMove;
        }

        private void ControlMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            IsDragging = true;
            var draggableControl = sender as Control;
            _clickPosition = e.GetPosition(this);
            if (draggableControl != null) draggableControl.CaptureMouse();
        }

        private void ControlMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            IsDragging = false;
            var draggable = sender as Control;
            if (draggable == null) return;
            var transform = draggable.RenderTransform as TranslateTransform;
            if (transform != null)
            {
                for (var i = 0; i<_data.Points.Count; i++)
                {
                    _data.Points[i] = new Point(_data.Points[i].X + transform.Value.OffsetX, _data.Points[i].Y + transform.Value.OffsetY);
                }
            }
            Points = GetStringFromPoints(_data.Points);
            OnPropertyChanged("Points");

            draggable.RenderTransform = new TranslateTransform();
            draggable.ReleaseMouseCapture();

        }

        private void ControlMouseMove(object sender, MouseEventArgs e)
        {
            var draggableControl = sender as Control;

            if (!IsDragging || draggableControl == null) return;
            var currentPosition = e.GetPosition(Parent as UIElement);

            var transform = draggableControl.RenderTransform as TranslateTransform;
            if (transform == null)
            {
                transform = new TranslateTransform();
                draggableControl.RenderTransform = transform;
            }

            transform.X = currentPosition.X - _clickPosition.X;
            transform.Y = currentPosition.Y - _clickPosition.Y;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
